/**
 * 
 */
package neptune.manager.model.cluster;

import java.util.ArrayList;

import neptune.manager.NeptuneManager;
import neptune.manager.model.topology.Node;
import neptune.manager.model.topology.NotEnoughResourcesException;

/**
 * Questa classe rappresenta una macchina fisica. Da notare che i metodi
 * {@link Node#addHostedNode(Node)}, {@link Node#getHostedNodes()},
 * {@link Node#removeHostedNode(Node)} sono overloaded poich� in un nodo fisico
 * non � riportato l'intero albero del nodo ma soltanto il riferimento al nodo
 * virtuale ospitato (il riferimento e' costituito dal suo nome completo:
 * nome_nodo.nome_esperimento).
 * 
 * @author Roberto Bifulco [info@robertobifulco.it, robertobifulco.it]
 * 
 */
public class PhysicalNode extends Node {

	// La PCU del nodo
	private PCU pcu;

	public PhysicalNode(String description, String id, String name) {
		super(description, id, name);
	}

	public PCU getPcu() {
		return pcu;
	}

	public void setPcu(PCU pcu) {
		this.pcu = pcu;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * neptune.manager.model.topology.Node#addHostedNode(neptune.manager.model
	 * .topology.Node)
	 */
	/**
	 * Questo metodo non adrebbe usato con un nodo fisico, a meno di modificare
	 * l'id del node che si passa come argomento, in modo da includere
	 * l'identificativo della topologia cui appartiene tale nodo.<br>
	 * <br>
	 * Il problema sorge poiche' in {@link Node} si prevede che i nodi
	 * appartengano tutti alla stessa topologia. Viceversa, in un nodo fisico,
	 * anche se estende la classe Node, i nodi fanno riferimento a topologie
	 * esterne, poich� il nodo fisico fa parte del cluster.<br>
	 * <br>
	 * Per utilizzare comunque questo metodo, si deve quindi cambiare l'id del
	 * nodo da "nodeId" a "nodeId.topologyId". Dove topologyId e'
	 * l'identificativo della topologia cui appartiene il nodo.
	 */
	@Override
	public void addHostedNode(Node node) throws NotEnoughResourcesException {
		if (node.getId().split(NeptuneManager.EXPID_NODEID_SEPARATOR).length != 2)
			throw new RuntimeException("Unsupported Operation: "
					+ "the method addHostedNode into PhysicalNode "
					+ "class cannot be used"
					+ " with a Node argument whom nodeId "
					+ "isn't a fully qualified node id.");

		super.addHostedNode(node);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * neptune.manager.model.topology.Node#removeHostedNode(neptune.manager.
	 * model.topology.Node)
	 */
	@Override
	public void removeHostedNode(Node node) {
		if (node.getId().split(NeptuneManager.EXPID_NODEID_SEPARATOR).length != 2)
			throw new RuntimeException("Unsupported Operation: "
					+ "the method removeHostedNode into PhysicalNode "
					+ "class cannot be used"
					+ " with a Node argument whom nodeId "
					+ "isn't a fully qualified node id.");

		super.removeHostedNode(node);
	}

	/**
	 * Rimuove un nodo virtuale da quelli ospitati dalla macchina fisica
	 * 
	 * @param node
	 * @param topologyId
	 * @throws NotEnoughResourcesException
	 */
	public void removeHostedNode(Node node, String topologyId) {
		if (node.getId().split(NeptuneManager.EXPID_NODEID_SEPARATOR).length != 2)
			node.setId(node.getId() + NeptuneManager.EXPID_NODEID_SEPARATOR
					+ topologyId);

		super.removeHostedNode(node);
	}

	/**
	 * Aggiunge un nodo virtuale fra quelli ospitati dalla macchina fisica
	 * 
	 * @param node
	 * @param topologyId
	 * @throws NotEnoughResourcesException
	 */
	public void addHostedNode(Node node, String topologyId)
			throws NotEnoughResourcesException {
		if (node.getId().split(NeptuneManager.EXPID_NODEID_SEPARATOR).length != 2)
			node.setId(node.getId() + NeptuneManager.EXPID_NODEID_SEPARATOR
					+ topologyId);
		addHostedNode(node);
	}

	/**
	 * Questo metodo viene adoperato per impostare "manualmente" gli
	 * identificativi dei nodi ospitati su questa macchina fisica. Si presuppone
	 * che dopo l'utilizzo di questo metodo, sia eseguito un qualche controllo
	 * sulla macchina fisica, per garantire l'assenza di situazioni non
	 * contemplate o illegali.
	 * 
	 * @param nodes
	 */
	public void setHostedNodes(ArrayList<String> nodes) {
		hostedNodes = nodes;
	}
}
